<template>
    <div>
        <el-card>
            <el-form :model="form" :inline="true" class="filter-form">
                <el-form-item label="用户名">
                    <el-input v-model="form.username" placeholder="请输入用户名" clearable />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="fetchData">搜索</el-button>
                    <el-button type="default" @click="resetForm">重置</el-button>
                </el-form-item>
            </el-form>
        </el-card>
        <el-card style="margin-top: 5px;">
            <el-button type="primary" @click="centerDialogVisible = true">新增用户</el-button>
            <el-button type="danger" @click="batchDeleteUser" :disabled="!selectIds.length">批量删除</el-button>
            <el-table border :data="tableData" class="table-main" @selection-change="handleSelectionChange">
                <el-table-column align="center" type="selection" width="55" />
                <el-table-column align="center" label="序号" width="60" type="index" />
                <el-table-column align="center" label="用户名字" width="150" prop="username" />
                <el-table-column align="center" label="用户名称" width="150" prop="name" />
                <el-table-column align="center" label="用户角色" show-overflow-tooltip min-width="150" prop="roleName" />
                <el-table-column align="center" label="创建时间" width="170" prop="createTime" />
                <el-table-column align="center" label="更新时间" width="170" prop="updateTime" />
                <el-table-column align="center" label="操作" fixed="right" width="320">
                    <template #="{ row }">
                        <el-button icon="user" type="primary" @click="assignRoles(row)">分配角色</el-button>
                        <el-button icon="edit" type="primary" @click="showUserInfo(row)">编辑</el-button>
                        <el-button icon="delete" type="danger" @click="deleteUser(row.id)">删除</el-button>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
                :page-sizes="[10, 20, 30, 40]" layout="prev, pager, next, jumper, ->, sizes, total" :total="total"
                @change="fetchData" />
        </el-card>
        <el-dialog :title="dialogTitle" v-model="centerDialogVisible" @closed="restRuleFormRef" width="30%"
            align-center>
            <el-form :model="userEntry" label-width="auto" :rules="rules" ref="ruleFormRef" status-icon>
                <el-form-item label="用户名" prop="username">
                    <el-input v-model="userEntry.username" placeholder="请输入用户名" clearable style="width:60%" />
                </el-form-item>
                <el-form-item label="用户名称" prop="name">
                    <el-input v-model="userEntry.name" placeholder="请输入用户名称" clearable style="width:60%" />
                </el-form-item>
                <el-form-item label="密码" prop="password" v-if="!userEntry.id">
                    <el-input v-model="userEntry.password" placeholder="请输入密码" clearable show-password style="width:60%"
                        type="password" />
                </el-form-item>
                <el-form-item label="手机号" prop="phone">
                    <el-input v-model="userEntry.phone" placeholder="请输入手机号" maxlength="11" clearable
                        style="width:60%" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button type="primary" @click="saveUserInfo" :loading="loading">保存</el-button>
                <el-button type="default" @click="centerDialogVisible = false">取消</el-button>
            </template>
        </el-dialog>


        <el-drawer v-model="drawer" title="分配角色">
            <el-form :model="rolesFrom" label-width="auto">
                <el-form-item label="用户名">
                    <el-input :model-value="rolesFrom.name" disabled style="width:60%" />
                </el-form-item>
                <el-form-item label="职位列表">
                    <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange"
                        style="width: 100%;">
                        全选
                    </el-checkbox>
                    <el-checkbox-group v-model="rolesFrom.selectRoles" @change="handleCheckedCitiesChange">
                        <el-checkbox style="width: 35%" v-for="role in rolesFrom.allRoles" :value="role.id"
                            :key="role.id">
                            {{ role.roleName }}
                        </el-checkbox>
                    </el-checkbox-group>
                </el-form-item>
            </el-form>
            <template #footer>
                <div style="flex: auto">
                    <el-button type="primary" :loading="loading" @click="saveRoles">保存</el-button>
                    <el-button type="default" @click=" drawer = false">取消</el-button>
                </div>
            </template>
        </el-drawer>
    </div>
</template>

<script setup lang='ts' name='User'>
import { type CheckboxValueType, type FormInstance, type FormRules } from 'element-plus';
import { reqUserPage, reqUserUpdate, reqUserSave, reqUserDelete, reqUserBatchDelete, reqUserRoleAssign, reqDoAssignRole } from '@/api/user';
import type { ResponseData } from '@/api/type';
import type { UserInfo, UserRoleInfo } from '@/api/user/type';

let form = reactive({
    username: ''
});
let tableData = ref<UserInfo[]>()

let userEntry: UserInfo = reactive({
    username: "",
    password: "123456789",
    name: "",
    phone: "13100000000",
    createTime: "",
    updateTime: "",
    roleName: "",

});
let rolesFrom = reactive<{
    userId: number | undefined,
    name: string,
    allRoles: UserRoleInfo[],
    selectRoles: number[]
}>({
    userId: undefined,
    name: "",
    allRoles: [],
    selectRoles: []
})

let currentPage = ref<number>(1)
let pageSize = ref<number>(10)
let total = ref<number>(0)
let centerDialogVisible = ref<boolean>(false)
let ruleFormRef = ref<FormInstance>();
let selectIds = ref<number[]>([]);
const dialogTitle = computed(() => userEntry.id ? '编辑用户' : '新增用户');
const loading = ref<boolean>(false);
const drawer = ref<boolean>(false);
const checkAll = ref(false)
const isIndeterminate = ref(true)
const validatorUserName = (_rule: any, value: any, callback: any) => {
    if (value && /^[a-zA-Z0-9]{5,10}$/.test(value)) {
        callback()
    } else {
        callback(new Error('用户名为英文或数字长度在5到10之间'))
    }
}

const rules = ref<FormRules<UserInfo>>({
    name: [
        { required: true, message: '用户名称不能空', trigger: ['blur'] },
    ],
    phone: [
        { required: true, message: '手机号不能空', trigger: 'blur' },
        { pattern: /^1[3-9]\d{9}$/, message: '手机号格式不正确', trigger: ['blur'] },
    ],
    username: [
        { required: true, message: '用户名不能空', trigger: 'blur' },
        { validator: validatorUserName, trigger: ['blur'] }
    ],
    password: [
        { required: true, message: '密码不能空', trigger: 'blur' },
        { min: 6, max: 10, message: '密码长度在6到10之间', trigger: ['blur'] },
    ],
});

const fetchData = async () => {
    reqUserPage(currentPage.value, pageSize.value, form.username).then(res => {
        total.value = res.data.total
        tableData.value = res.data.records
    }).catch((error: ResponseData<String>) => {
        ElMessage.error(('获取用户失败。') + error.message);
    })
}

const resetForm = () => {
    form.username = ''
    fetchData()
}

const restRuleFormRef = () => {
    // 清空表单字段
    ruleFormRef.value?.resetFields();
    Object.assign(userEntry, {
        username: "",
        name: "",
        password: "123456789",
        phone: "13100000000",
        createTime: "",
        updateTime: "",
        roleName: "",
        id: undefined,
    })
}

const showUserInfo = (user: UserInfo) => {
    centerDialogVisible.value = true
    Object.assign(userEntry, user)
}

const saveUserInfo = () => {
    ruleFormRef.value?.validate().then(() => {
        loading.value = true
        if (userEntry.id) {
            const { password, ...user } = userEntry
            reqUserUpdate(user).then(() => {
                ElMessage.success('用户信息更新成功');
                centerDialogVisible.value = false
                fetchData()
            }).catch((error: ResponseData<String>) => {
                ElMessage.error(('用户信息更新失败。') + error.message);
            })
        } else {
            reqUserSave(userEntry).then(() => {
                ElMessage.success('用户信息保存成功');
                centerDialogVisible.value = false
                fetchData()
            }).catch((error: ResponseData<String>) => {
                ElMessage.error(('用户信息保存失败。') + error.message);
            })
        }
        loading.value = false
    }).catch(() => {
        ElMessage.error('表单验证失败，请检查输入内容。');
    })
}

const deleteUser = (id: number) => {
    ElMessageBox.confirm('确认删除该用户吗？', '提示', {
        type: 'warning'
    }).then(() => {
        reqUserDelete(id).then(() => {
            ElMessage.success('用户删除成功');
            fetchData()
        }).catch((error: ResponseData<String>) => {
            ElMessage.error(('用户删除失败。') + error.message);
        })
    })
}

const batchDeleteUser = () => {
    ElMessageBox.confirm('确认批量删除选中用户吗？').then(() => {
        reqUserBatchDelete(selectIds.value).then(() => {
            ElMessage.success('用户批量删除成功');
            fetchData()
        }).catch((error: ResponseData<String>) => {
            ElMessage.error(('用户批量删除失败。') + error.message);
        })
    }).catch(() => {
        // cancel
    })
}

const handleSelectionChange = (newSelection: UserInfo[]) => {
    const validIds = newSelection
        .map(item => item.id)
        .filter(id => id !== undefined) as number[];
    selectIds.value = validIds
}

const assignRoles = (user: UserInfo) => {
    drawer.value = true
    Object.assign(rolesFrom, {
        name: user.name,
        userId: user.id
    })
    reqUserRoleAssign(user.id as number).then(res => {
        rolesFrom.allRoles = res.data.allRolesList
        rolesFrom.selectRoles = res.data.assignRoles.map(s => s.id as number)
    }).then(() => {
        if (rolesFrom.selectRoles.length === 0) {
            checkAll.value = false;
            isIndeterminate.value = false;
        } else {
            checkAll.value = rolesFrom.allRoles.length === rolesFrom.selectRoles.length;
            isIndeterminate.value = !checkAll.value;
        }
    })
}

const handleCheckAllChange = (val: CheckboxValueType) => {
    rolesFrom.selectRoles = val ? rolesFrom.allRoles.map(s => s.id as number) : []
    isIndeterminate.value = false
}
const handleCheckedCitiesChange = (value: CheckboxValueType[]) => {
    const checkedCount = value.length
    checkAll.value = checkedCount === rolesFrom.allRoles.length
    isIndeterminate.value = checkedCount > 0 && checkedCount < rolesFrom.allRoles.length
}

const saveRoles = () => {
    loading.value = true
    reqDoAssignRole({ userId: rolesFrom.userId as number, roleIdList: rolesFrom.selectRoles }).then(() => {
        ElMessage.success('角色分配成功');
        drawer.value = false
        fetchData()
    }).catch((error: ResponseData<String>) => {
        ElMessage.error(('角色分配失败。') + error.message);
    })
    loading.value = false
}

onMounted(() => {
    fetchData()
})
</script>

<style scoped lang='scss'>
.filter-form {
    display: flex;
    justify-content: space-between;
}

.table-main {
    height: calc(100vh - $base-tabbar-height - 265px);
    margin: 10px 0px;
}
</style>